tags : [[lisp]] [[functional programming]] [[Scheme]]
Some of my examples are written in Emacs Lisp, as at the time I hadn’t installed a Scheme interpreter. It doesn’t make a huge difference.
an atom is a simple element, separated by spaces
a list is a series of atoms, surrounded by parentheses
an atom or a list
car
retrieves first element of list
(car '(123))
cdr
retrieves everything besides the first element of a list
(cdr '(a b c))
cons
adds an atom to the front of a list
(cons 100 '(a b c))
(cons '(a b) '(c d))
null
tests for empty lists
(null ())
atom
tests for atoms
(atom 123)
eq
tests equality for non-numeric atoms
(eq 'a 'b)
null?
first!cons
is for building listscdr
of the rest of the list(defun firsts (l)
(cond
((null l) '())
(t (cons (car (car l)) (firsts (cdr l)) ))))
(firsts '((a b) (c d))) ;; => (a c)
a | c |
In Scheme (and other Lisps?) a * suffix means “repeat this throughout the list.” More specifically, it means to recur on the car
of the list.
For example:
(rember* 'sauce ((tomato sauce) bean sauce)) ;; => ((tomato) bean)
(rember 'sauce ((tomato sauce) bean sauce)) ;; => ((tomato) bean sauce)
The first commandment says that, when recurring, you must ask between two to three questions. For a list of atoms, it’s “null?
” and “else
”, and for S-expressions, it’s “null?
”, “atom? (car l)
”, and “else
”
The fourth commandment says that, when recurring, you must change at least one argument. When traversing over a list, decrement the list using cdr
The sixth commandment is very important: “simplify only after the function is correct”
The Seventh Commandment : Recur on the subparts that are of the same nature
An attempt at value
(for only +
) in Emacs Lisp:
“`emacs-lisp
(defun my-value (nexp)
(cond
((atom nexp) nexp)
((eq (car (cdr nexp)) ‘+) (+ (value (car nexp)) (value (car (cdr (cdr nexp))))))
(t nexp)))
(my-value '(1 + 2))
```
The Eighth Commandment : Use help functions to abstract from representations
Rendering context...